package ar.edu.sovietrussia.customcomponents.abm.book;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.apache.wicket.authroles.authorization.strategies.role.annotations.AuthorizeInstantiation;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.ListMultipleChoice;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.spring.injection.annot.SpringBean;

import services.book.AuthorService;
import services.book.BookService;
import services.book.PublisherService;
import ar.edu.sovietrussia.customcomponents.bookviews.BookModel;
import ar.edu.sovietrussia.customcomponents.maincomponentviews.MainLibrarianComponent;
import ar.edu.sovietrussia.customcomponents.util.BackToMainWindowGenericComponent;
import ar.edu.sovietrussia.customcomponents.util.IFeedbacker;
import ar.edu.sovietrussia.customcomponents.util.WrapperPanel;
import books.Category;
import dtos.AuthorDTO;
import dtos.BookInfoDTO;
import dtos.PublisherDTO;

/**
 * Class for Book ABM handling
 */

@AuthorizeInstantiation("ADMIN")
public abstract class AbmBookInfoPanel extends BackToMainWindowGenericComponent implements IFeedbacker {

    private static final long serialVersionUID = 1L;

    @SpringBean
    private AuthorService authorService;

    @SpringBean
    private BookService bookService;

    @SpringBean
    private PublisherService publisherService;

    public AbmBookInfoPanel(final String id, final BookModel model) {
        super(id, model);

        AbmBookInfoPanel.this.addComponents();
    }

    public AbmBookInfoPanel(final String id) {
        super(id, new BookModel(new BookInfoDTO()));

        this.addComponents();
    }

    private void addComponents() {

        this.addForm("form");

    }

    private void addForm(final String id) {

        final BookModel bookModel = (BookModel) this.getDefaultModel();

        Form<BookModel> bookForm = new Form(id, bookModel) {
            private static final long serialVersionUID = 1L;
        };

        bookForm.add(new TextField<String>("title"));
        bookForm.add(new TextField<String>("description"));
        bookForm.add(new TextField<String>("isbn"));

        bookForm.add(this.authorListChoice("authors"));
        bookForm.add(this.categoriesListChoice("categories"));
        bookForm.add(this.publishersListChoice("publisher"));

        bookForm.add(new Label("title_label", "Title:"));
        bookForm.add(new Label("categories_label", "Categories:"));
        bookForm.add(new Label("authors_label", "Authors:"));
        bookForm.add(new Label("isbn_label", "ISBN:"));
        bookForm.add(new Label("desc_label", "Description:"));
        bookForm.add(new Label("publisher_label", "Publisher:"));

        bookForm.add(new Button("submit") {

            private static final long serialVersionUID = -4012436557532793987L;

            @Override
            public void onSubmit() {
                BookInfoDTO book = bookModel.getObject();
                AbmBookInfoPanel.this.onSubmitBook(book);
            }
        });

        // Go Back Button
        bookForm.add(new Button("back_button") {
            private static final long serialVersionUID = 5119888790644143879L;

            @Override
            public void onSubmit() {
                AbmBookInfoPanel.this.replaceWith(new MainLibrarianComponent(AbmBookInfoPanel.this.getId()) {

                    private static final long serialVersionUID = 1L;

                    @Override
                    public FeedbackPanel getFeedbackTarget() {
                        return AbmBookInfoPanel.this.getFeedbackTarget();
                    }

                    @Override
                    public Map<String, WrapperPanel> getReplaceableComponents() {
                        return AbmBookInfoPanel.this.getReplaceableComponents();
                    }

                });
            }
        });

        this.add(bookForm);
    }

    private DropDownChoice<?> publishersListChoice(final String id) {
        DropDownChoice<?> combo = new DropDownChoice(id, this.getAvailablePublishers(), new PropertyChoiceRenderer(
                "id", "name"));

        combo.setNullValid(false);
        return combo;
    }

    private List<PublisherDTO> getAvailablePublishers() {
        // obtener las editoriales
        List<PublisherDTO> publishers = this.getPublisherService().getAllPublishersDTO();

        return publishers;
    }

    private ListMultipleChoice<String> categoriesListChoice(final String id) {

        List<Category> choices = this.getAvailableCategories();

        ListMultipleChoice listChoice = new ListMultipleChoice(id, choices);

        listChoice.setMaxRows(5);

        return listChoice;
    }

    private ListMultipleChoice<?> authorListChoice(final String id) {

        List<AuthorDTO> choices = this.getAvailableAuthors();

        @SuppressWarnings("unchecked")
        ListMultipleChoice<?> listChoice = new ListMultipleChoice<Object>(id, choices, new PropertyChoiceRenderer("id",
                "name"));

        listChoice.setMaxRows(5);

        return listChoice;
    }

    public abstract void onSubmitBook(final BookInfoDTO book);

    public List<AuthorDTO> getAvailableAuthors() {
        // obtener los autores que haya
        return this.getAuthorService().getAllAuthorsDTO();
    }

    private List<Category> getAvailableCategories() {
        return Arrays.asList(Category.values());
    }

    public void setAuthorService(final AuthorService authorService) {
        this.authorService = authorService;
    }

    public AuthorService getAuthorService() {
        return this.authorService;
    }

    public void setBookService(final BookService bookService) {
        this.bookService = bookService;
    }

    public BookService getBookService() {
        return this.bookService;
    }

    public void setPublisherService(final PublisherService publisherService) {
        this.publisherService = publisherService;
    }

    public PublisherService getPublisherService() {
        return this.publisherService;
    }
}
